home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d3 / ddjhptxt.arc / FRIED.LST < prev    next >
File List  |  1990-06-05  |  20KB  |  535 lines

  1. LISTING ONE
  2.  
  3. #include <dos.h>        /* i.e. just like MS C */
  4. void note();
  5. main()
  6. {
  7.         note(440,500);
  8. }
  9. void note(pitch, duration)
  10. int pitch,duration;
  11. {
  12.            int u,v;
  13.         union REGS regs;
  14.         unsigned int_count,int_duration,count,int_pitch;
  15.            int_pitch = 1190000/pitch;
  16.         int_duration = (duration*1821)/10000;
  17.         regs.x.ax = 0;                          /* call timer */
  18.         int86(0x1a, ®s, ®s);
  19.         int_count = regs.x.dx;  /* internal count = lowest 16-bits of time*/
  20.         u = inp(0x61) | 3;    /* Turn on channel 2 of 8255 using port 61h */
  21.         outp(0x61,u);         /* send byte to back */
  22.         outp(0x43,0xb6);      /* set up I/O register */
  23.         outp(0x42,(char) int_pitch);    /* send freq to latch */
  24.         outp(0x42,(int_pitch >> 8));
  25.         do {
  26.                 regs.x.ax = 0;       /* use timer to get end of duration */
  27.                 int86(0x1a, ®s, ®s);
  28.                 count = regs.x.dx;   /* use lowest 16-bits of count */
  29.         } while (count < int_duration + int_count);
  30.         v = inp(0x61) & 0xfc;        /* turn off the sound */
  31.         outp(0x61,v);
  32. }
  33.  
  34.  
  35. LISTING TWO
  36.  
  37. #define outp(p,v) dx = p;al = v;asm(dx,al,"     out     dx,al")
  38. #define inp(p,v)  dx = p;asm(dx,"       in      al,dx",al);v = al
  39.         unsigned char x,y,page = 0; /* globals for pc_test */
  40. void note();
  41. main()
  42. {
  43.         note(440,500);
  44. }
  45.  
  46. void note(pitch, duration)
  47. int pitch,duration;
  48. {
  49.         reg$eax unsigned short ax;
  50.         reg$eax unsigned char al,x,y;
  51.         reg$edx unsigned short dx;
  52.         reg$ah  unsigned char ah;
  53.         /* this section was added for play */
  54.      unsigned int_count,int_duration,count,int_pitch;
  55.         if (duration == 0) return;
  56.         int_duration = (duration*1821)/10000;
  57. /*      We left the original interrupt as a comment for comparison purposes
  58. */
  59. /*      regs.x.ax = 0;       call timer */
  60. /*      int86(0x1a, ®s, ®s);  */
  61. /*      int_count = regs.x.dx; internal count = lowest 16-bits of time*/
  62. /*      the inline assembly language is line for line identical in function
  63.         although there is an obvious difference in format. */
  64.         ax = 0;
  65.         asm(ax,"        int     01ah",dx);
  66.         int_count = dx;
  67.  
  68.         if (pitch==0) goto time_it;
  69.         int_pitch = 1190000/pitch;
  70. /*      The port input is a little different using inline asm macros */
  71. /*      x = inp(0x61) | 3;      the original code becomes */
  72.         inp(0x61,x);    /* Turn on channel 2 of 8253 using port 61H */
  73.         x = x | 3;      /* After read turn on lowest 2 bits */
  74. /*      The outp macro looks just like the outp function */
  75.            outp(0x61,x);          /* send byte to back */
  76.         outp(0x43,0xb6);       /* set up I/O register */
  77.         outp(0x42,(char) int_pitch);    /* send freq to latch */
  78.         outp(0x42,(int_pitch >> 8));
  79. time_it:
  80.         do {
  81.                 ax = 0;         /* use timer to wait for end */
  82.                 asm(ax,"        int     01ah",dx);
  83.                 count = dx;
  84.         } while (count < int_duration + int_count);
  85.         inp(0x61,y);    /* Turn off channel 2 */
  86.         y = y & 0xfc;   /* use 1111 1100 to turn off lowest 2 bits only */
  87.         outp(0x61,y);
  88. }
  89.  
  90.  
  91. LISTING THREE
  92.  
  93.         name sound4.c
  94.         .387
  95.         assume  cs:codeseg
  96.         assume  ds:dataseg
  97. codeseg segment dword er use32 public 'code'
  98. dataseg segment dword rw use32 public 'data'
  99.  
  100. dataseg ends
  101.         align   4
  102.  
  103. _note   proc    near
  104.  
  105.         push            edi
  106.         push            esi
  107.         push            ebx
  108.         mov             ebx,[esp]+16
  109.         cmp             dword ptr [esp]+20,0
  110.         jne             L17     short
  111.         pop             ebx
  112.         pop             esi
  113.         pop             edi
  114.         ret
  115.         align   4
  116. L17:
  117.         mov             ecx,10000
  118.         imul            eax,[esp]+20,1821
  119.         cdq
  120.         idiv            ecx
  121.         mov             edi,eax
  122.         mov             ax,0
  123.         int             01ah
  124.         movzx   esi,dx
  125.         or              ebx,ebx
  126.         jne             L16     short
  127.         jmp             L13
  128.         align   4
  129. L16:
  130.         mov             eax,1190000
  131.         cdq
  132.         idiv            ebx
  133.         mov             ebx,eax
  134.         mov             dx,97
  135.         in              al,dx
  136.         or              al,3
  137.         mov             dx,97
  138.         out             dx,al
  139.         mov             dx,67
  140.         mov             al,182
  141.         out             dx,al
  142.         mov             dx,66
  143.         mov             al,bl
  144.         out             dx,al
  145.         mov             dx,66
  146.         mov             eax,ebx
  147.         shr             eax,byte ptr 8
  148.         out             dx,al
  149.         align   4
  150. L14:
  151.         align   4
  152. L13:
  153.         mov             ax,0
  154.         int             01ah
  155.         movzx   ecx,dx
  156.         mov             eax,edi
  157.         add             eax,esi
  158.         cmp             eax,ecx
  159.         ja              L13     short
  160.         mov             dx,97
  161.         in              al,dx
  162.         and             al,252
  163.         mov             dx,97
  164.         out             dx,al
  165.         align   4
  166. L9:
  167.         pop             ebx
  168.         pop             esi
  169.         pop             edi
  170.         ret
  171.         align   4
  172. _note   endp
  173. dataseg segment dword rw use32 public 'data'
  174.  
  175. ;_ax                    ax              local
  176. ;_al                    al              local
  177. ;_x                     al              local
  178. ;_y                     al              local
  179. ;_dx                    dx              local
  180. ;_ah                    ah              local
  181. ;_int_count     esi             local
  182. ;_int_duration  edi             local
  183. ;_count         ecx             local
  184. ;_int_pitch     ebx             local
  185.  
  186. ;parameters
  187. ;_pitch         ebx             local
  188. ;_duration      [esp]+20        local
  189. dataseg ends
  190.         end
  191.  
  192.  
  193. LISTING FOUR
  194.  
  195. #include <stdio.h>
  196. #include <dos1.h>
  197. #include <ctype.h>
  198. /*      ***WARNING*** if you change the scale so that it starts
  199.         on middle C, instead of A, the resulting routine will
  200.         exhibit not only the look and feel of the BASIC PLAY
  201.         command, but its sound as well.
  202. */
  203. #define aa      440             /* middle a = 440 */
  204. #define as      469             /* a sharp */
  205. #define bb      493
  206. #define cc      523             /* middle c */
  207. #define cs      556
  208. #define dd      587
  209. #define ds      624
  210. #define ee      659
  211. #define ff      698
  212. #define fs      739
  213. #define gg      783
  214. #define gs      832
  215.  
  216. #define outp(p,v) dx = p;al = v;asm(dx,al,"     out     dx,al")
  217. #define inp(p,v)  dx = p;asm(dx,"       in      al,dx",al);v = al
  218.         unsigned char x,y,page = 0; /* globals for pc_test */
  219. void note();
  220. void look_ahead_and_toot();
  221. void play();
  222. int check_length();
  223. int check_integer();
  224. int gobble_dots();
  225.                 /* the buffer for the notes to be input */
  226. int  pitch;
  227. int  count = 0;                 /* points to current location in string */
  228. int  length = 4;                        /* default is a quarter note */
  229. int  tempo = 240;               /* = 120 beats per minute */
  230. int  duration = 60;             /* = tempo/length =1/4 @ 120 bpm */
  231. int  shift = 0;                 /* current octave shift factor */
  232. char c_note;                    /* the current note character used for diag
  233. */
  234.  
  235. main()
  236. {       /* Stereo version of Heart and Soul for two PCs
  237.         lifted from a BASIC program Transcribed by
  238.         Michael Benjamin Fried - Age 11 */
  239.         /* bass line plays on first machine */
  240.         play( "T150L8O4CCEEAACCDDFFO3GG>BBO4");
  241.         play( "L8O4CCEEAACCDDFFO3GG>BBO4");
  242.  
  243.         /* while melody plays on a second */
  244.         play( "O4L4CCC.P32C8B8A8B8C8D8P32");
  245.         play( "EEE.P32E8D8C8D8E8F8G.C.>A8<G8F8E8D8CB8Ao3G8FFGGo4");
  246. }
  247. void play(in_string)
  248. char in_string[];
  249. {
  250. int temp_duration;              /* gets set by L or change in l */
  251. int temp_octave;                /* holds temporary octave */
  252. char    n_note;
  253. count = 0;
  254. printf("note = %s \n",in_string);
  255. while (c_note = in_string[count]){ /* loop till out of characters */
  256.         n_note = in_string[count+1];  /* look ahead 1 char now */
  257.         switch(c_note){                 /* switch on current note */
  258.  
  259.                 case 'A':               /* do a,a sharp and a flat */
  260.                 case 'a':
  261.                         pitch = aa;     /* set the default to A natural */
  262.                         if ((n_note == '#')||(n_note == '+')){
  263.                                 pitch = as; /* it was A sharp */
  264.                                 count++;
  265.                                 }
  266.                         if (n_note == '-'){ /* it was A flat */
  267.                                 pitch = gs; /* A flat == G sharp */
  268.                                 count++;
  269.                                 }
  270.                         look_ahead_and_toot(in_string); /* self explanatory
  271. */
  272.                         break;                           /* line duration */
  273.  
  274.                 case 'B':               /* B is just like A */
  275.                 case 'b':
  276.                         pitch = bb;
  277.                         if ((n_note == '#')||(n_note == '+')){
  278.                                 pitch = cc; /* B sharp is actually C */
  279.                                 count++;
  280.                                 }
  281.                         if (n_note == '-'){
  282.                                 pitch = as; /* B flat is A sharp */
  283.                                 count++;
  284.                                 }
  285.                         look_ahead_and_toot(in_string);
  286.                         break;
  287.  
  288.                 case 'C':                       /* C is just like A */
  289.                 case 'c':
  290.                         pitch = cc;
  291.                         if ((n_note == '#')||(n_note == '+')){
  292.                                 pitch = cs;
  293.                                 count++;
  294.                                 }
  295.                         if (n_note == '-'){ /* C flat is actually B */
  296.                                 pitch = bb; /* and a perfectly legal note */
  297.                                 count++;
  298.                                 }
  299.                         look_ahead_and_toot(in_string);
  300.                         break;
  301.  
  302.                 case 'D':               /* D is like A */
  303.                 case 'd':
  304.                         pitch = dd;
  305.                         if ((n_note == '#')||(n_note == '+')){
  306.                                 pitch = ds;
  307.                                 count++;
  308.                                 }
  309.                         if (n_note == '-'){
  310.                                 pitch = cs; /* D flat is C sharp */
  311.                                 count++;
  312.                                 }
  313.                         look_ahead_and_toot(in_string);
  314.                         break;
  315.  
  316.                 case 'E':               /* E is like A */
  317.                 case 'e':
  318.                         pitch = ee;
  319.                         if ((n_note == '#')||(n_note == '+')){
  320.                                 pitch = ff; /* E sharp is F */
  321.                                 count++;
  322.                                 }
  323.                         if (n_note == '-'){
  324.                                 pitch = ds;
  325.                                 count++;
  326.                                 }
  327.                         look_ahead_and_toot(in_string);
  328.                         break;
  329.  
  330.                 case 'F':               /* F is like A */
  331.                 case 'f':
  332.                         pitch = ff;
  333.                         if ((n_note == '#')||(n_note == '+')){
  334.                                 pitch = fs;
  335.                                 count++;
  336.                                 }
  337.                         if (n_note == '-'){
  338.                                 pitch = ee;
  339.                                 count++;
  340.                                 }
  341.                         look_ahead_and_toot(in_string);
  342.                         break;
  343.  
  344.                 case 'G':               /* G is like A */
  345.                 case 'g':
  346.                         pitch = gg;
  347.                         if ((n_note == '#')||(pitch == '+')){
  348.                                 pitch = gs;
  349.                                 count++;
  350.                                 }
  351.                         if (n_note == '-'){
  352.                                 pitch = fs;
  353.                                 count++;
  354.                                 }
  355.                         look_ahead_and_toot(in_string);
  356.                         break;
  357.  
  358.                 case 'L':               /* set length */
  359.                 case 'l':
  360.                         if(temp_duration = check_length(in_string)){
  361.                                 duration = tempo/temp_duration;
  362.                                 length = temp_duration;
  363.                                 }
  364.                         break;
  365.                 case '>':               /* go up an octave */
  366.                         shift++;
  367.                         break;
  368.  
  369.                 case '<':               /* go down an octave */
  370.                         shift--;
  371.                         break;
  372.  
  373.                 case 'O':               /* chose an octave */
  374.                 case 'o':
  375.                         temp_octave = n_note - '0';
  376.                         if ((temp_octave < 0)||(temp_octave > 6)){
  377.                                 printf("octave out of range");
  378.                                 break;
  379.                                 }
  380.                         switch(n_note){
  381.                                 case '0':
  382.                                         shift = -4;
  383.                                         break;
  384.                                 case '1':
  385.                                         shift = -3;
  386.                                         break;
  387.                                 case '2':
  388.                                         shift = -2;
  389.                                         break;
  390.                                 case '3':
  391.                                         shift = -1;
  392.                                         break;
  393.                                 case '4':               /* default octave */
  394.                                         shift = 0;
  395.                                         break;
  396.                                 case '5':
  397.                                         shift = 1;
  398.                                         break;
  399.                                 case '6':
  400.                                         shift = 2;
  401.                                         break;
  402.                                 }
  403.                         count++;        /* advance over digit */
  404.                         break;
  405.  
  406.                 case 'P':               /* set pause/rest length */
  407.                 case 'p':               /* issue note of freq 0 to rest */
  408.                 case 'R':               /* computer scientists pause */
  409.                 case 'r':               /* but musicians rest! */
  410.                         pitch = 0;
  411.                         look_ahead_and_toot(in_string);
  412.                         break;
  413.  
  414.                 case 'T':               /* set tempo */
  415.                 case 't':
  416.                         temp_duration = check_integer(in_string);
  417.                         if ((temp_duration < 32)||(temp_duration > 255))
  418.                                 break;
  419.                         tempo = temp_duration*2;
  420.                         duration = tempo/length;
  421.                         break;
  422.  
  423.                 case ' ':               /* spaces are gobbled up */
  424.                         break;
  425.  
  426.                 default:                /* had a problem so issue error */
  427.                         printf("Syntax error in character %d \n",count);
  428.                         goto terminate;
  429.                 }
  430.         count++;        /* advance pointer to next note */
  431.         }
  432. terminate:
  433. }
  434. /* The trickiest part of the syntax are the optional trailers that
  435.         can follow each note. These include an optional integer that
  436.         specifies a quarter (4) or eighth note (8) (or any integer
  437.         between 1 and 64) and 1 or more optional dots, each of which
  438.         increases the current duration by half. This section parses
  439.         these trailers, and then uses the global variables that contain
  440.         the tempo and octave to compute the duration and pitch, and
  441.         then call note. Note that rests are handled as notes of 0 pitch.
  442. */
  443.  
  444. void look_ahead_and_toot(in_string)
  445. char in_string[];
  446. {
  447. int temp_duration;
  448. if (temp_duration = check_length(in_string)) /* if non zero have a temp */
  449.         temp_duration = tempo/temp_duration;  /* compute new duration */
  450. else
  451.         temp_duration = duration;        /* if 0 play default duration */
  452. /* check for dot, and if found call gobble_dots to increase temp_duration */
  453. if (in_string[count+1] == '.')
  454.         temp_duration = gobble_dots(temp_duration,in_string);
  455.                 /* range check octaves */
  456. if (shift < -4)
  457.         shift = -4;
  458. if (shift > 2)
  459.         shift = 2;
  460.                 /* shift to change octaves */
  461. if (shift < 0)  /* negative shifts go down in frequency */
  462.         pitch = pitch >> -shift;
  463. else            /* positive shifts go up in frequency */
  464.         pitch = pitch << shift;
  465.         /* optional diagnostics for debugging */
  466. printf("%c = %d duration = %d octave = d\n",
  467.                         c_note,pitch,temp_duration,shift+4);
  468.         /* finally we are ready for a little toot */
  469. note(pitch,temp_duration);
  470. }
  471. int gobble_dots(duration_in,in_string)
  472. int duration_in;
  473. char in_string[];
  474. {
  475. int duration_out;
  476. int duration_increment;
  477. duration_out = duration_in;
  478. duration_increment = duration_in;
  479. /* gobble as long as there are dots adding half the prior duration inc */
  480. while (in_string[count+1] == '.'){
  481.         duration_increment = duration_increment >> 1; /* divide it by 2 */
  482.         duration_out = duration_out + duration_increment;
  483.         count++;                        /* advance string pointer */
  484.         }
  485. return(duration_out);
  486. }
  487. /* returns 1-64 in range 1-64 else returns 0 */
  488. int check_length(in_string)
  489. char in_string[];
  490. {
  491. int result = check_integer(in_string);
  492.         if ((result < 1) || (result > 64))
  493.                 return(0);      /* out of range */
  494.         else
  495.                 return(result); /* in range */
  496. }
  497. /* 0 1 to 999 if 1 - 999 found and advances count */
  498. /* returns 0 otherwise */
  499. int check_integer(in_string)
  500. char in_string[];
  501. {
  502. int n_char,m_char,l_char;
  503. n_char = in_string[count+1] - '0';
  504. if ((n_char > 9) || (n_char < 0)) return (0); /* return if out of range */
  505. count++;                        /* we found a digit so advance count */
  506. m_char = in_string[count+1] - '0';   /* check next integer */
  507. if ((m_char > 9) || (m_char < 0))
  508.         return (n_char);
  509. else
  510.         count++;                /*found second didit so advance again */
  511. l_char = in_string[count+1] - '0';
  512. if ((l_char > 9) || (l_char < 0)) /* check last possible digit */
  513.         return (n_char*10+m_char); /* compute 2 digit result */
  514. else {
  515.         count++;                /* we found a third and last digit */
  516.         return(n_char*100+m_char*10+l_char);
  517.         }
  518. }
  519. /* optional main program works as an interactive interpreter */
  520. char note_string[120];
  521. /*
  522. main()
  523. {
  524. do{
  525.         puts("enter note ");
  526.         fflush(stdin);
  527.         gets(note_string);
  528.         printf("\nnote string = %s \n",note_string);
  529.         play();
  530.         } while (strlen(note_string) > 0);
  531. }
  532. */
  533.  
  534.  
  535.